#include <QtGui>
#include "xbeltree.h"

int i_num = 1;        //отсчет номеров итемов от 1
int Vlosh = 100;     //вложенность - количество уровней
QString str_mes_posl, str_mes_dr;   //строки для сообщений показателей эргономичности при инициализации расчета
QString str_mes_posl_ves, str_mes_dr_ves;   //строки для сообщений показателей эргономичности при инициализации расчета


XbelTree::XbelTree(QWidget *parent)
    : QTreeWidget(parent)
{

    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    QStringList labels;

    labels << tr("Название")
            << tr("Показатель \nэргономичности")
            << tr("Коэффициент \nвесомости")
            << tr("Номер \nсвойства");

    setHeaderLabels(labels);

//    folderIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
//                         QIcon::Normal, QIcon::Off);
//    folderIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirOpenIcon),
//                         QIcon::Normal, QIcon::On);
//    elementIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
}

bool XbelTree::read(QIODevice *device)
{
    QString errorStr;
    int errorLine;
    int errorColumn;

    if (!domDocument.setContent(device, true, &errorStr, &errorLine,
                                &errorColumn)) {
        QMessageBox::information(window(), tr("Информация Metodika"),
                                 tr("Ошибка в линии %1, column %2:\n%3")
                                 .arg(errorLine)
                                 .arg(errorColumn)
                                 .arg(errorStr));
        return false;
    }

    QDomElement root = domDocument.documentElement();
    if (root.tagName() != "xbel") {
        QMessageBox::information(window(), tr("Информация Metodika"),
                                 tr("Этот файл не XBEL файл."));
        return false;
    } else if (root.hasAttribute("version")
               && root.attribute("version") != "1.0") {
        QMessageBox::information(window(), tr("Информация Metodika"),
                                 tr("Версия этого файла XBEL не 1.0 "
                                    "file."));
        return false;
    }

    clear();

    disconnect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
               this, SLOT(updateDomElement(QTreeWidgetItem*,int)));

    QDomElement child = root.firstChildElement("folder");
    while (!child.isNull()) {
        parseFolderElement(child);
        child = child.nextSiblingElement("folder");
    }

    connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
            this, SLOT(updateDomElement(QTreeWidgetItem*,int)));

    return true;
}

bool XbelTree::write(QFile *file)
{

    QXmlStreamWriter xmlWriter(file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("xbel");
    xmlWriter.writeAttribute(tr("version"),tr("1.0"));

    for(int i =0; i <XbelTree::topLevelItemCount(); ++i)
    {
        writeIndexEntry(&xmlWriter, XbelTree::topLevelItem(i));
    }
    xmlWriter.writeEndDocument();
    file->close();
    if(file->error())
    {

       return false;
    }
    return true;
}

void XbelTree::writeIndexEntry(QXmlStreamWriter *xmlWriter, QTreeWidgetItem *item)
{
    xmlWriter->writeStartElement("folder");
    xmlWriter->writeAttribute("title",item->text(0));
    xmlWriter->writeAttribute("value_ergo",item->text(1));
    xmlWriter->writeAttribute("value_ves",item->text(2));
    xmlWriter->writeAttribute("value_number",item->text(3));
    xmlWriter->writeAttribute("folded",item->text(4));
    for(int i =0; i<item->childCount(); ++i)
        writeIndexEntry(xmlWriter,item->child(i));
    xmlWriter->writeEndElement();
}

void XbelTree::updateDomElement(QTreeWidgetItem *item, int column)
{
    QDomElement element = domElementForItem.value(item);
    if (!element.isNull()) {
        if (column == 0) {
            QDomElement oldTitleElement = element.firstChildElement("title");
            QDomElement newTitleElement = domDocument.createElement("title");

            QDomText newTitleText = domDocument.createTextNode(item->text(0));
            newTitleElement.appendChild(newTitleText);

            element.replaceChild(newTitleElement, oldTitleElement);
        } else {
            if (element.tagName() == "element")
                element.setAttribute("value", item->text(1));
        }
    }
}

void XbelTree::parseFolderElement(const QDomElement &element,
                                  QTreeWidgetItem *parentItem)
{
    QTreeWidgetItem *item = createItem(element, parentItem);

    QString title = element.attribute("title");
    QString value_ergo = element.attribute("value_ergo");
    QString value_ves = element.attribute("value_ves");
    QString value_number = element.attribute("value_number");
    QString foldedString = element.attribute("folded");

    item->setFlags(item->flags() | Qt::ItemIsEditable);
    item->setIcon(0, folderIcon);
    item->setText(0, title);
    item->setText(1, value_ergo);
    item->setText(2, value_ves);
    item->setText(3, value_number);
    item->setText(4, foldedString);

    bool folded = (element.attribute("folded") != "no");
    setItemExpanded(item, !folded);

    QDomElement child = element.firstChildElement();
    while (!child.isNull()) {
        if (child.tagName() == "folder") {
            parseFolderElement(child, item);
        } else if (child.tagName() == "separator") {
            QTreeWidgetItem *childItem = createItem(child, item);
            childItem->setFlags(item->flags() & ~(Qt::ItemIsSelectable | Qt::ItemIsEditable));
            childItem->setText(0, QString(30, 0xB7));
        }
        child = child.nextSiblingElement();
    }
}

QTreeWidgetItem *XbelTree::createItem(const QDomElement &element,
                                      QTreeWidgetItem *parentItem)
{
    QTreeWidgetItem *item;
    if (parentItem) {
        item = new QTreeWidgetItem(parentItem);
    } else {
        item = new QTreeWidgetItem(this);
    }
    domElementForItem.insert(item, element);
    return item;
}

bool XbelTree::slot_insertItem(bool child)
{
    QDomElement root = domDocument.documentElement();
    QList<QTreeWidgetItem *> list;
    list = XbelTree::selectedItems();

    if(list.isEmpty())
    {
        QMessageBox::about(this,tr("Предупреждение"),tr("Не выбран элемент для определения места вставки"));
        return false;
    }

        if(!child)
    list[0] = list[0]->parent();
    QTreeWidgetItem *item = createItem(root,list[0]);
    QString title = QObject::tr("Folder");

    item->setFlags(item->flags() | Qt::ItemIsEditable);
    item->setIcon(0, folderIcon);
    item->setText(0, title);
    item->setText(1, tr("value"));
    item->setText(2, tr("value"));
    item->setText(3, tr("value"));
    item->setText(4, tr("no"));

    return true;
}

bool XbelTree::slot_deleteItem()
{
    QList<QTreeWidgetItem *> list;
    list = XbelTree::selectedItems();

    if(list.isEmpty())
    {
        QMessageBox::about(this,tr("Предупреждение"),tr("Не выбран элемент для удаления"));
        return false;
    }

    list[0]->~QTreeWidgetItem();
    return true;
}

bool XbelTree::slot_raschet()
{
    str_mes_posl_ves.clear();
    str_mes_posl.clear();
    str_mes_dr.clear();

    for(int i =0; i <XbelTree::topLevelItemCount(); ++i)
    {
        ras_init(XbelTree::topLevelItem(i));        //Приводим к нормальному виду со значениями только в последних child
    }

        if(!str_mes_posl.isNull())  {
            QMessageBox::about(this,tr("Предупреждение"),tr("Не заполнен показатель эргономичности элемента ").append(str_mes_posl));
        return false;
        }
        if(!str_mes_dr.isNull())    {
            QMessageBox::about(this,tr("Предупреждение"),tr("Заполнен показатель эргономичности элемента ").append(str_mes_dr).append(tr(" который должен рассчитываться")));
        return false;
        }
        if(!str_mes_posl_ves.isNull())  {
            QMessageBox::about(this,tr("Предупреждение"),tr("Не заполнен коэффициент весомости элемента ").append(str_mes_posl_ves));
        return false;
        }

        for(int i =0; i <Vlosh; ++i)
    {
        for(int i =0; i <XbelTree::topLevelItemCount(); ++i)
        {
            ras_func(XbelTree::topLevelItem(i));            //расчет value
        }
    }

        //расчет number
        for(int i =0; i <XbelTree::topLevelItemCount(); ++i)
        {
            slot_ras_number(XbelTree::topLevelItem(i));
        }

    return true;
}

void XbelTree::ras_init(QTreeWidgetItem *item)
{
    for(int i =0; i<item->childCount(); ++i)
    {
        //проверяем элементы на заполненность их показателя весомости
        if(item->child(i)->text(2)==NULL)  {
            str_mes_posl_ves.append(item->child(i)->text(0)).append(" ");
        }
        //проверить последние child на заполненность их показателя эргономичности
        if(item->child(i)->child(0)==NULL)
        {
            if(item->child(i)->text(1)==NULL)  {
                str_mes_posl.append(item->child(i)->text(0)).append(" ");
            }
        }
        else
        {
            if(item->child(i)->text(1)!=NULL)
            {
                str_mes_dr.append(item->child(i)->text(0)).append(" ");
            }
        }
        ras_init(item->child(i));       //рекурсия
    }
}

void XbelTree::ras_func(QTreeWidgetItem *item)
{

        QString mas_ergo[100];     //количество дочерних элементов одного элемента
        QString mas_ves[100];

    for(int i =0; i<item->childCount(); ++i)
    {
        if(item->child(i)->text(1)!=NULL)            //то это элементы последние
        {
            mas_ergo[i] = item->child(i)->text(1);
            mas_ves[i] = item->child(i)->text(2);
        }
        ras_func(item->child(i));               //рекурсия
    }

        float value = 0;

    for(int i =0;!mas_ergo[i].isNull();i++)         //формула которая плюсует элементы в value
    {
    value = value + mas_ergo[i].toFloat()*mas_ves[i].toFloat();
    }

    if(!mas_ergo[0].isNull())
    {
    item->setText(1,QString::number(value));    //записываем значение в итем
    }

}

void XbelTree::slot_ras_number(QTreeWidgetItem *item)
{

    for(int i =0; i<item->childCount(); ++i)
        slot_ras_number(item->child(i));

    item->setText(3,QString::number(i_num));    //записываем значение в итем

    ++i_num;
}

bool XbelTree::slot_new(QFile *file_new)
{
//    QFile *file_ex = new QFile(file_new);
//    file_ex->~QFile();
//    file_ex->setFileName("bla bla bla");

    QXmlStreamWriter xmlWriter(file_new);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("xbel");
    xmlWriter.writeAttribute(tr("version"),tr("1.0"));

    xmlWriter.writeStartElement("folder");
    xmlWriter.writeAttribute("title",tr("Эргономичность"));
    xmlWriter.writeAttribute("value_ergo","");
    xmlWriter.writeAttribute("value_ves","");
    xmlWriter.writeAttribute("value_number","");
    xmlWriter.writeAttribute("folded","");

    xmlWriter.writeEndDocument();

    file_new->close();

    if(file_new->error())
    {
       return false;
    }

    if(!read(file_new))
    return false;

    return true;
}
